﻿using System.Net.Mime;
using HelenServer.FileStorage.Contracts;

namespace HelenServer.FileStorage.Controllers;

[ApiController]
[Route("[controller]")]
public class FileController : ControllerBase
{
    private readonly IFileStorageService _service;

    public FileController(IFileStorageService service)
    {
        _service = service;
    }

    [HttpPost]
    public async Task<OperationResult> UploadFileAsync()
    {
        if (Request.Form.Files.Count < 1)
        {
            return OperationResult.Error(new FileNotFoundException());
        }
        else
        {
            var file = Request.Form.Files[0];

            using var fileStream = file.OpenReadStream();

            var __buffer = new byte[fileStream.Length];
            await fileStream.ReadAsync(__buffer, HttpContext.RequestAborted);

            var model = new UploadModel
            {
                Name = file.FileName,
                Extension = Path.GetExtension(file.FileName),
                Buffer = __buffer
            };

            var operation = HttpContext.GetOperation(model);

            var result = await _service.UploadFileAsync(operation, HttpContext.RequestAborted);

            return result;
        }
    }

    [HttpGet("download")]
    public async Task<IActionResult> DownloadFileAsync([FromQuery] int id)
    {
        var operation = HttpContext.GetOperation(id);

        var result = await _service.DownloadFileAsync(operation);

        if (result.Succeed)
        {
            var model = result.Data;

            var stream = new MemoryStream(model.Buffer);

            return this.BpctResult(stream, MediaTypeNames.Application.Octet, model.Name, "\"download\"");
        }

        return this.NotFound();
    }

    [HttpDelete]
    public async Task<OperationResult> RemoveFileAsync([FromQuery] int id)
    {
        var operation = HttpContext.GetOperation(id);

        var result = await _service.RemoveFileAsync(operation);

        return result.Succeed && result.Data ? OperationResult.OK("删除成功") : OperationResult.Failed(result.Message);
    }
}